import dayjs from 'dayjs';
import { Thread, Worker,spawn } from 'threads';
import * as net from 'net';
import config from '../../config';
import DataService from '../service/Admin/Data.service';
import { logger } from './log';
import websocketIo from './websocket.io';
import DeviceStatusManager, { OfflineEvent } from './DeviceStatusManager';
import eventEmit from './emitEvent';
import System from './system';

interface SocketConnection {
    socket: any;
    address: string;
    port: number;
    isConnected: boolean;
    gateway_name?: string;
}

class TcpClient {
    private readonly MAX_RECONNECT_DELAY = 5 * 60 * 1000; // 5分钟
    private readonly RECONNECT_JITTER = 500; // 500毫秒的抖动范围
    private readonly MAX_DATA_CACHE_SIZE = 20000;
    public static instance: TcpClient | null = null;
    private SystemInfo: System | null = null;
    private address: string = ''
    private port: number = 8080
    public socket: any = null; // 保持向后兼容
    public sockets: Map<string, SocketConnection> = new Map();
    private reconnectingSockets: Set<string> = new Set(); // 重连锁
    private isConnected: boolean = false;
    public gatewayList: Array<{ip: string,id: number,name: string}> = []; // 连接成功的网关列表
    public currentGatewayIp: string = '';
    private repeatTime: number = 15
    private theadList: Thread[] | any[] = [];
    private threadNum: number = 15;
    private currentThreadIndex: number = 0; // 轮询线程索引
    private threadProcessingCount: number[] = []; // 每个线程的处理计数
    private threadInitializationPromise: Promise<void>;
    private dataCache: any[] = [];
    private saveInterval: NodeJS.Timeout;
    private deviceStatusManager: DeviceStatusManager;
    private readonly MAX_ALARM_CACHE_LIMIT = 30;
    private alarmState: Map<string, {isAlarm: boolean, count: number}> = new Map();
    private pendingCommands: Map<string, {commandType: string, client: any, timestamp: number}> = new Map();
    private atResponseCallbacks: ((address: string, response: string) => void)[] = [];
    private totalLinkGateways: string[] = []; // 待连接的总设备网关
    private connectionCheckInterval: NodeJS.Timeout; // 连接检查定时器
    private heartbeatState = new Map<string, {
        consecutiveFailures: number;
        lastResponse: number;
        lastSendTime: number;
    }>();
    private diskFree: number;
    private reconnectAttempts: Map<string, number> = new Map();
    private updateDisk: NodeJS.Timeout;
    private readonly maxReconnectAttempts = 20; // 最大重连次数
    private readonly reconnectBaseDelay = 1000; // 初始重连延迟（毫秒）
    public static getInstance(): TcpClient {
        if (!TcpClient.instance) {
            this.instance = new TcpClient();
        }
        return TcpClient.instance as TcpClient;
    }

    // 获取网关在线列表
    public getGatewayOnlineList() { 
        let gatewayList: Array<{ip: string,id: number,name: string}> = [];
        let index = 0;

        let configIpList: string[] = config.networkAddresses?.split(',') || [];
        let gatewayNameList: string[] = config.gatewayNames?.split(',') || [];
        this.sockets.forEach((item,address) => {
            if (item.isConnected) {
                index++;
                if (configIpList.includes(address)) {
                    gatewayList.push({
                        ip: address,
                        id: index,
                        name: `${gatewayNameList[index -1]}`
                    });
                }
            }
        })
        this.gatewayList = gatewayList;
        let isCurrrent = this.gatewayList.some(item => item.ip === this.currentGatewayIp)
        if (!isCurrrent) {
            this.currentGatewayIp = gatewayList[0]?.ip || '';
        }
        return gatewayList;
    }    
    // 为每个网关维护独立的数据缓冲区
    private gatewayBuffers: Map<string, Buffer> = new Map();


    public receiveData(address: string, socketConnection?: SocketConnection) {
        const targetSocket = socketConnection ? socketConnection.socket : this.socket;
        
        // 初始化该网关的缓冲区
        if (!this.gatewayBuffers.has(address)) {
            this.gatewayBuffers.set(address, Buffer.alloc(0));
        }
        
        targetSocket.on('data', async (chunk: Buffer) => {
            // 收到任何数据都表示连接活跃，重置心跳状态
            const state = this.heartbeatState.get(address);
            if (state) {
                state.consecutiveFailures = 0;
                state.lastResponse = Date.now();
            }
            await this.threadInitializationPromise;

            // 获取或创建该网关的缓冲区
            let currentBuffer = this.gatewayBuffers.get(address);
            if (!currentBuffer) {
                currentBuffer = Buffer.alloc(0);
            }

            // 将新数据追加到该网关的缓冲区
            const newBuffer = Buffer.concat([currentBuffer, chunk]);

            this.gatewayBuffers.set(address, newBuffer);

            // 限制缓冲区大小，防止内存溢出
            if (newBuffer.length > 10240) { // 10KB限制
                logger.warn(`[${address}] 缓冲区过大(${newBuffer.length}字节)，清空缓冲区`);
                this.gatewayBuffers.set(address, Buffer.alloc(0));
                return;
            }

            // 分离AT指令和十六进制数据包
            const { atCommands, hexDataBuffer, remainingBuffer } = this.separateATCommandsAndHexData(newBuffer);
            
            // console.log(atCommands)
            // 更新缓冲区为剩余未处理的数据
            this.gatewayBuffers.set(address, remainingBuffer);
            
            // 处理AT指令
            if (atCommands.length > 0) {
                for (const atCommand of atCommands) {
                
                    this.handleATCommandResponse(address, atCommand);
                }
            }
            
            // 处理十六进制数据包
            if (hexDataBuffer.length > 0) {
                this.processBufferInThread(address, hexDataBuffer);
            }
        });
    }

    /**
     * 分离AT指令和十六进制数据包
     * @param buffer 原始数据缓冲区
     * @returns 分离后的AT指令数组、十六进制数据缓冲区和剩余缓冲区
     */
    private separateATCommandsAndHexData(buffer: Buffer): {
        atCommands: string[];
        hexDataBuffer: Buffer;
        remainingBuffer: Buffer;
    } {
        const atCommands: string[] = [];
        const hexDataChunks: Buffer[] = [];
        let currentPos = 0;
        let remainingBuffer = Buffer.alloc(0);
        while (currentPos < buffer.length) {
            // 检查是否为十六进制数据包起始标志 (F7 F7)
            if (currentPos + 1 < buffer.length &&
                buffer[currentPos] === 0xF7 && buffer[currentPos + 1] === 0xF7) {
                

                // 至少需要5个字节才能读取长度 (帧头2 + ID1 + Func1 + Len1)
                if (currentPos + 5 > buffer.length) {
                    // 头部信息都不完整，等待更多数据
                    
                    remainingBuffer = buffer.slice(currentPos);
                    break;
                }

                const dataLen = buffer[currentPos + 4];

                // 对 dataLen 进行范围检查，无效则丢弃并前进
                if (dataLen === 0 || dataLen > 50) { 
                    
                    currentPos++; // 丢弃这个坏的F7，从下一个字节开始
                    continue;
                }

                // 验证帧尾是否是7f7f
                let packetFound = false;
                const totalLen = dataLen + 9; // 唯一合法的总长度
                

                if (currentPos + totalLen <= buffer.length) {
                    // 严格检查帧尾是否为 7F7F
                    if (buffer[currentPos + totalLen - 2] === 0x7F && buffer[currentPos + totalLen - 1] === 0x7F) {
                        const packet = buffer.slice(currentPos, currentPos + totalLen);
                        hexDataChunks.push(packet);
                        
                        currentPos += totalLen;
                        packetFound = true;
                    }
                }

                // 如果验证失败
                if (!packetFound) {
                    // 判断是否因为数据不完整而失败
                    if (currentPos + totalLen > buffer.length) {
                        // 数据确实不完整，保留并等待
                        // console.log(`[DEBUG] Incomplete packet, remaining buffer length: ${buffer.length - currentPos}`);
                        remainingBuffer = buffer.slice(currentPos);
                        break;
                    } else {
                        // 丢弃这个F7，从下一个字节开始重新寻找F7F7
                        currentPos++;
                        continue;
                    }
                }
            } else {
                // 寻找下一个 F7F7 包头，在此之前的所有数据都视为潜在的文本数据
                const nextHeaderIndex = buffer.indexOf(Buffer.from([0xF7, 0xF7]), currentPos);

                // 如果找不到下一个包头，则剩余所有数据都是文本
                const endOfTextPos = nextHeaderIndex === -1 ? buffer.length : nextHeaderIndex;

                const textDataBuffer = buffer.slice(currentPos, endOfTextPos);

                if (textDataBuffer.length > 0) {
                    // 尝试按行分割，处理可能的多条AT指令
                    const textData = textDataBuffer.toString();
                    const commands = textData.split(/\r?\n/).map(s => s.trim()).filter(s => s.length > 0);

                    commands.forEach(cmd => {
                        if (this.isATCommand(cmd)) {
                            atCommands.push(cmd);
                        } else {
                            remainingBuffer = Buffer.concat([remainingBuffer, textDataBuffer]);
                        }
                    });
                }

                currentPos = endOfTextPos;
            }
        }
        
        // 合并所有十六进制数据包
        const hexDataBuffer = hexDataChunks.length > 0 ? Buffer.concat(hexDataChunks) : Buffer.alloc(0);
        
        return {
            atCommands,
            hexDataBuffer,
            remainingBuffer
        };
    }
    
    /**
     * 检查字符串是否为AT指令
     */
    private isATCommand(text: string): boolean {
        if (!text || text.length === 0) return false;
        
        const cleanText = text.trim();
        
        return cleanText.includes("AT+") || 
               cleanText.includes("AT?") ||
               (cleanText.includes("OK") && cleanText.length < 100) ||
               (cleanText.includes("ERROR") && cleanText.length < 100) ||
               cleanText.match(/^\s*(AT|\+|OK|ERROR)/i) !== null ||
               cleanText.includes("FRAT=") ||
               cleanText.includes("GAIN=") ||
               cleanText.includes("VER=") ||
               cleanText.includes("DTYPE=") ||
               (cleanText.includes("FF") && cleanText.length > 12) ||
               cleanText.includes("CELLID=")
    }
    
    /**
     * 检查字符串是否可能是AT指令的开始
     */
    private couldBeATCommandStart(text: string): boolean {
        if (!text || text.length === 0) return false;
        
        const cleanText = text.trim();
        
        // 检查是否以AT指令常见开头开始
        return cleanText.startsWith("AT") ||
               cleanText.startsWith("+") ||
               cleanText.startsWith("OK") ||
               cleanText.startsWith("ERROR") ||
               cleanText.startsWith("FRAT") ||
               cleanText.startsWith("GAIN") ||
               cleanText.startsWith("VER") ||
               cleanText.startsWith("DTYPE") ||
               cleanText.startsWith("CELLID");
    }

    private async processBufferInThread(address: string, buffer: Buffer) {
        try {
            // 检查缓冲区是否为空或过小
            if (buffer.length === 0) {
                return;
            }
            
            // 选择工作线程
            const currentThread = this.theadList[this.currentThreadIndex];
            const selectedThreadIndex = this.currentThreadIndex;
            this.currentThreadIndex = (this.currentThreadIndex + 1) % this.threadNum;
            
            // 记录线程使用统计
            this.threadProcessingCount[selectedThreadIndex]++;
            
            // 将Buffer转换为hex字符串后传递给工作线程处理
            const hexData = buffer.toString('hex');
            
            // 添加超时处理
            const timeoutPromise = new Promise((_, reject) => {
                setTimeout(() => reject(new Error('工作线程处理超时')), 5000);
            });
            const processingPromise = currentThread({
                hexData: hexData,
                address: address,
                settingData: eventEmit.settingData || {}
            });
            
            const result = await Promise.race([processingPromise, timeoutPromise]) as any;
            
            if (result && result.processedData && result.remainingBuffer !== undefined) {
                // 更新缓冲区（移除已处理的数据）
                const remainingBuffer = typeof result.remainingBuffer === 'string' 
                    ? Buffer.from(result.remainingBuffer, 'hex')
                    : Buffer.alloc(0);
                this.gatewayBuffers.set(address, remainingBuffer);
     
                // 处理解析出的数据
                for (const jsonData of result.processedData) {
                    if (jsonData && jsonData.ID !== undefined) {
                        const saveData = {
                            gateway_ip: address,
                            module_id: jsonData.ID,
                            tem: jsonData.data[0],
                            hum: jsonData.data[1],
                            pre: jsonData.data[2],
                            inf: jsonData.data[3],
                            uvc: jsonData.data.slice(4).join(','),
                            info: JSON.stringify(jsonData),
                            time: new Date().toLocaleTimeString()
                        };
                          if (this.dataCache.length >= this.MAX_DATA_CACHE_SIZE) {
                              this.dataCache.shift(); // 移除数组第一个元素
                            }
                            this.dataCache.push(saveData);
                       
                            websocketIo.getInstance.recordDeviceData(jsonData.ID.toString(), address,{
                                battery: jsonData.battery? Number(jsonData.battery) : undefined, // 解析电池电量
                                signal: jsonData.signal? Number(jsonData.signal) : undefined, // 解析信号强度
                            });
                            // WebSocket通知
                        if (websocketIo.getInstance.socketObj) {
                           
                            // 修改发送条件：当前选中的网关 或 有报警状态 或 正常数据都发送
                            const shouldSend = this.currentGatewayIp === address || 
                            jsonData.sta.some(e => e > 0) 
                            
                            if (shouldSend) {
                                websocketIo.getInstance.socketObj.send(JSON.stringify({
                                    action: "sendData", 
                                    ...jsonData,
                                    gatewayIp: address
                                }));
                            }
                        }
                    }
                }
            } else {
                logger.warn(`[${address}] 工作线程返回无效结果`);
            }
        } catch (error) {
            logger.error(`线程处理错误 [${address}]: ${(error as Error).message}`, {
                error: (error as Error).stack,
                address: address
            });
            
            // 改进的错误处理：不清空整个缓冲区，而是尝试跳过可能有问题的数据
            this.handleBufferProcessingError(address, buffer, error as Error);
        }
    }
    
    /**
     * 处理缓冲区处理错误的安全方法
     * @param address 网关地址
     * @param buffer 当前处理的缓冲区
     * @param error 错误信息
     */
    private handleBufferProcessingError(address: string, buffer: Buffer, error: Error): void {
        const currentBuffer = this.gatewayBuffers.get(address);
        if (!currentBuffer || currentBuffer.length === 0) {
            return;
        }
        
        // 如果是超时错误，可能是数据量太大，尝试减少处理的数据量
        if (error.message.includes('超时')) {
            logger.warn(`[${address}] 工作线程处理超时，尝试减少数据量`);
            // 只保留后一半的数据，丢弃前一半可能有问题的数据
            const halfLength = Math.floor(currentBuffer.length / 2);
            const reducedBuffer = currentBuffer.slice(halfLength);
            this.gatewayBuffers.set(address, reducedBuffer);
            return;
        }
        
        // 对于其他错误，尝试寻找下一个可能的数据包起始位置
        let nextValidPos = -1;
        
        // 寻找下一个F7 F7标志（数据包起始）
        for (let i = 1; i < currentBuffer.length - 1; i++) {
            if (currentBuffer[i] === 0xF7 && currentBuffer[i + 1] === 0xF7) {
                nextValidPos = i;
                break;
            }
        }
        
        if (nextValidPos > 0) {
            // 找到下一个可能的数据包起始位置，丢弃之前的数据
            const remainingBuffer = currentBuffer.slice(nextValidPos);
            this.gatewayBuffers.set(address, remainingBuffer);
            // logger.info(`[${address}] 跳过 ${nextValidPos} 字节的问题数据，保留 ${remainingBuffer.length} 字节`);
        } else {
            // 没有找到有效的数据包起始标志，但不清空整个缓冲区
            // 只保留最后的一小部分数据，以防包含不完整的有效数据包
            const keepSize = Math.min(256, currentBuffer.length); // 保留最后256字节
            const keepBuffer = currentBuffer.slice(-keepSize);
            this.gatewayBuffers.set(address, keepBuffer);
            logger.warn(`[${address}] 未找到有效数据包标志，保留最后 ${keepSize} 字节数据`);
        }
    }
    async initCheckGateway() {

        this.threadInitializationPromise = this.initTheadList();
        this.deviceStatusManager = DeviceStatusManager.getInstance();
        // 使用递归的setTimeout确保数据保存不会并发执行
        const loop = async () => {
            try {
                await this.batchSaveData();
            } catch (err) {
                logger.error("保存循环出错:", err);
            } finally {
                // 无论成功失败，都在60秒后再次启动
                setTimeout(loop, 60 * 1000);
            }
        };
        loop(); // 立即启动第一次

        // 获取需要连接的网关
        this.totalLinkGateways = config.networkAddresses?.split(',') || [];
        
         // 设置定时器，每30秒清理一次超时的待处理指令
        setInterval(() => this.cleanupPendingCommands(), 30 * 1000);
           // 启动连接状态检查定时器ss
        this.connectionCheckInterval = setInterval(() => this.checkConnections(), 30*1000); // 每30秒检查一次

        this.SystemInfo = new System();
        this.initDiskFree()
        this.updateDisk = setInterval(async () => {
            this.initDiskFree()
        }, 1000 * 30);
    }
    async initDiskFree(): Promise<void> {
        const info: Record<string,any> | undefined = await this.SystemInfo?.getDiskInfo()
        this.diskFree = parseFloat(info?.free) || 10;
    }
    // 初始化线程列表
    async initTheadList(): Promise<void> {
        const threadPromises: Promise<Thread>[] = [];
        for (let i = 0; i < this.threadNum; i++) {
            threadPromises.push(spawn(new Worker('./index')));
        }
        this.theadList = await Promise.all(threadPromises);
        this.threadProcessingCount = new Array(this.threadNum).fill(0);
        logger.info(`线程池初始化完成，共${this.threadNum}个线程.`);
        
        // 每30秒输出线程负载统计
        setInterval(() => {
            const totalProcessed = this.threadProcessingCount.reduce((sum, count) => sum + count, 0);
            if (totalProcessed > 0) {
                const loadDistribution = this.threadProcessingCount.map((count, index) => 
                    `线程${index}: ${count}次 (${(count/totalProcessed*100).toFixed(1)}%)`
                ).join(', ');
                logger.info(`线程负载分布: ${loadDistribution}`);
                // 重置计数器
                this.threadProcessingCount.fill(0);
            }
        }, 30000);
    }

    // 批量存储数据到数据库
    private async batchSaveData() {
        if (this.dataCache.length === 0) {
            return;
        }
        
        // 检查磁盘空间是否足够
        if (this.diskFree <= 1) {
            logger.error('磁盘空间不足，暂停数据存储操作。剩余空间：', this.diskFree, 'GB');
            return; // 磁盘空间不足，不执行存储操作
        }
        
        // 创建缓存副本并清空主缓存，防止在异步保存期间数据丢失
        const dataToSave = [...this.dataCache];
        this.dataCache = [];

        try {
            await DataService.batchSaveDataList(dataToSave);
        } catch (error) {
            logger.error('批量存储数据失败:', error);
            // 可选：将失败的数据重新放回缓存以便下次重试
            this.dataCache.unshift(...dataToSave);
        }
    }

    /**
     * 处理设备掉线事件
     */
    private handleDeviceOffline(event: OfflineEvent): void {
        logger.warn(`设备掉线事件 - 设备ID: ${event.deviceId}, 掉线时间: ${new Date(event.offlineTime).toLocaleString()}, 累计掉线次数: ${event.offlineCount}`);
        
        // 通过WebSocket通知前端设备掉线
        if (websocketIo.getInstance.socketObj) {
            websocketIo.getInstance.socketObj.send(JSON.stringify({
                action: "deviceOffline",
                data: event
            }));
        }
        
    }

    /**
     * 获取设备统计信息
     */
    public getDeviceStatistics(gatewayIp?: string) {
        return this.deviceStatusManager.getDeviceStatistics(gatewayIp);
    }

    /**
     * 获取指定设备状态
     */
    public getDeviceStatus(deviceId: string, gatewayIp?: string) {
        return this.deviceStatusManager.getDeviceStatus(deviceId, gatewayIp as string);
    }

    /**
     * 重置设备掉线计数
     */
    public resetDeviceOfflineCount(deviceId: string, gatewayIp?: string): boolean {
        return this.deviceStatusManager.resetDeviceOfflineCount(deviceId, gatewayIp as string);
    }

    /**
     * 获取所有socket连接状态
     */
    public getAllConnectionsStatus(): {ip: string, isConnected: boolean,name: string,id: number}[] {
        const status: {ip: string, isConnected: boolean,name: string,id: number}[] = [];
        let index = 0
        this.sockets.forEach((connection, key) => {
            index++
            status.push({
                id: index,
                ip: connection.address,
                isConnected: connection.isConnected,
                name: connection.gateway_name?? '未知网关'
            });
        });
        return status;
    }

    /**
     * 向所有连接的socket发送数据
     */
    public sendToAllConnections(data: any): void {
        this.sockets.forEach((connection, key) => {
            if (connection.isConnected && connection.socket) {
                try {
                    connection.socket.write(data);
                    // logger.info(`数据已发送到 ${connection.address}:${connection.port}`);
                } catch (error) {
                    logger.error(`发送数据到 ${connection.address}:${connection.port} 失败:`, error);
                }
            }
        });
    }

    /**
     * 向指定地址的socket发送数据
     */
    public sendToConnection(address: string, port: number, data: any): boolean {
        const connection = this.sockets.get(address);
        if (connection && connection.isConnected && connection.socket) {
            try {
                connection.socket.write(data);
                // logger.info(`数据已发送到 ${address}:${port}`);
                return true;
            } catch (error) {
                logger.error(`发送数据到 ${address}:${port} 失败:`, error);
                return false;
            }
        }
        
        logger.warn(`连接 ${address}:${port} 不存在或未连接`);
        return false;
    }

    /**
     * 连接多个服务器地址
     */
    public connectMultipleServers(addresses: string[], port: number,gateway_name: string[]) {
        this.port = port // 初始化这个网关的连接端口
        addresses.forEach((address,index) => {
            this.connectSingleServer(address, port,gateway_name[index]);
        });
    }

    
    // 通知前端网关列表需要更改
    private infoRefreshGatewayList() {
        // 发送给前端有新的设备连接了
        if (websocketIo.getInstance.socketObj) {
            let gatewayList = this.getAllConnectionsStatus();
            // 通知网关设备数量变化
            websocketIo.getInstance.socketObj.send(JSON.stringify({
                action: 'repeateConnect',
                data: gatewayList
            }));
            // 通知设备数量变化
            websocketIo.getInstance.notifyDeviceStatusUpdate();
        }
    }
    /**
     * 连接单个服务器
     */
    private connectSingleServer(address: string, port: number,gatewayName: string) {
        const socket = net.createConnection({
            host: address,
            port: port
        });

        socket.on('connect', () => {
            logger.info(`以太网通信连接成功: ${address}:${port}`);
            const connection: SocketConnection = {
                socket: socket,
                address: address,
                port: port,
                isConnected: true,
                gateway_name: gatewayName? gatewayName : '未知网关'
            };

            this.sockets.set(address, connection);
            this.reconnectAttempts.set(address, 0); // 连接成功，重置尝试次数
            this.reconnectingSockets.delete(address); // 连接成功，移除重连锁
            this.heartbeatState.set(address, { consecutiveFailures: 0, lastResponse: Date.now(), lastSendTime: 0 }); // 初始化心跳状态
            socket.setKeepAlive(true, 60000);
            this.receiveData(address, connection);
            // 通知前端
            this.infoRefreshGatewayList()

            // 初次连接需要去调用一次设备查询
            setTimeout(() => this.sendATCommand(address,"AT+DEV?","queryDevice"), 300);
        });

        socket.on('error', (err: any) => {
            logger.info(`连接错误 ${address}:${port}:`, err);
            socket.destroy()
        });

        socket.on('close', () => {
            try {
             logger.info(`连接已关闭: ${address}:${port}`);
                const socketObj = this.sockets.get(address)
                if (socketObj) {
                    socketObj.isConnected = false
                }
                socket.removeAllListeners()      
                this.handleDisconnect(address,port,gatewayName)
                // 通知前端
                this.infoRefreshGatewayList()   
            } catch(error) {
                logger.error(error)
            }
        });
    }

    private handleDisconnect(address: string, port: number, gatewayName: string) {
        if (this.reconnectingSockets.has(address)) {
            logger.info(`[${address}] 正在重连中，跳过此次断开处理...`);
            return;
        }

        // 清理该网关的所有资源
        this.heartbeatState.delete(address);
        this.sockets.delete(address);
        this.gatewayBuffers.delete(address);
        this.deviceStatusManager.removeDevicesByGateway(address);
        logger.warn(`[${address}] 连接已断开，相关资源已清理。`);

        // 实现指数退避重连
        const attempts = this.reconnectAttempts.get(address) || 0;

        const baseDelay = this.reconnectBaseDelay * Math.pow(2, attempts);
        const cappedDelay = Math.min(baseDelay, this.MAX_RECONNECT_DELAY);
         // 增加随机抖动
        const delay = cappedDelay + Math.floor(Math.random() * this.RECONNECT_JITTER);
        logger.info(`网关 ${address} 将在 ${delay / 1000} 秒后尝试重连... (第 ${attempts + 1} 次)`);

        this.reconnectingSockets.add(address); // 设置重连锁

        setTimeout(() => {
            this.reconnectingSockets.delete(address);
            this.connectSingleServer(address, port, gatewayName);
        }, delay);

        this.reconnectAttempts.set(address, attempts + 1);
    }

    private checkConnections() {
        const gatewayNames = config.gatewayNames?.split(',') || [];
        
        for (const [index, gateway_ip] of this.totalLinkGateways.entries()) {
            const socketConnection = this.sockets.get(gateway_ip);
            const gatewayName = gatewayNames[index] || '未知网关';

            if (socketConnection && socketConnection.isConnected) {
                this.sendHeartbeat(gateway_ip, gatewayName);
            } else {
                logger.info(`未找到网关 ${gateway_ip} 的连接或连接已断开，开始重连...`);
                this.handleDisconnect(gateway_ip, this.port, gatewayName);
            }
        }
    }

    private sendHeartbeat(gateway_ip: string, gatewayName: string) {
        const state = this.heartbeatState.get(gateway_ip);
        if (!state) return;

        const socketConnection = this.sockets.get(gateway_ip);
        if (!socketConnection || !socketConnection.isConnected) return;

        try {
            // 记录发送时间
            const sendTime = Date.now();
            state.lastSendTime = sendTime;
            
            // logger.info(`向网关 ${gateway_ip} 发送心跳指令: AT+CELLID?`);
            socketConnection.socket.write('AT+CELLID?\r\n');

            // 设置3秒超时检查
            setTimeout(() => {
                this.checkHeartbeatResponse(gateway_ip, gatewayName, sendTime);
            }, 3000);

        } catch (err) {
            logger.info(`向网关 ${gateway_ip} 发送心跳指令失败:`, err);
            state.consecutiveFailures++;
            if (state.consecutiveFailures >= 3) {
                logger.info(`网关 ${gateway_ip} 连续3次心跳发送失败，判定为掉线。`);
                this.handleDisconnect(gateway_ip, this.port, gatewayName);
            }
        }
    }

    

    private checkHeartbeatResponse(gateway_ip: string, gatewayName: string, sendTime: number) {
        const state = this.heartbeatState.get(gateway_ip);
        if (!state) return;

        // 检查是否在发送后收到了响应
        if (state.lastResponse > sendTime) {
            logger.info(`网关 ${gateway_ip} 心跳响应正常`);
            state.consecutiveFailures = 0; // 重置失败计数
        } else {
            state.consecutiveFailures++;
            logger.info(`网关 ${gateway_ip} 心跳超时 (第${state.consecutiveFailures}次)`);
            if (state.consecutiveFailures >= 3) {
                logger.info(`网关 ${gateway_ip} 连续3次心跳无响应，判定为掉线。`);
                this.handleDisconnect(gateway_ip, this.port, gatewayName);
            }
        }
    }
    /**
      * 处理AT指令响应
      */
     private handleATCommandResponse(address: string, response: string): void {
        
        //  logger.info(`收到来自 ${address} 的AT指令响应:`, response);
         
         // 通过所有注册的回调函数通知WebSocket有AT指令响应
         this.atResponseCallbacks.forEach(callback => {
             try {
                 callback(address, response);
             } catch (error) {
                 console.error('AT响应回调执行失败:', error);
             }
         });
         
         // 处理待处理的指令
         this.pendingCommands.forEach((command, key) => {
             if (key.startsWith(address)) {
                 // 根据响应内容判断指令执行结果
                 const isSuccess = response.includes("OK") && !response.includes("ERROR");
                 
                 // 这里可以根据具体的AT指令类型进行更详细的处理
                //  logger.info(`指令 ${command.commandType} 执行${isSuccess ? '成功' : '失败'}`);
                 
                 // 移除已处理的指令
                 this.pendingCommands.delete(key);
             }
         });
     }

    /**
     * 发送AT指令到指定网关
     */
    public sendATCommand(address: string, command: string, commandType: string = 'unknown'): boolean {
        const connection = this.sockets.get(address);
        if (!connection) {
            logger.warn(`连接 ${address} 不存在`);
            return false;
        }
        
        if (!connection.isConnected) {
            logger.warn(`连接 ${address} 未连接`);
            return false;
        }
        
        if (!connection.socket) {
            logger.warn(`连接 ${address} socket对象不存在`);
            return false;
        }
        
        try {
            // 记录待处理的指令
            const commandKey = `${address}_${commandType}_${Date.now()}`;
            this.pendingCommands.set(commandKey, {
                commandType: commandType,
                client: connection.socket,
                timestamp: Date.now()
            });
            
            // 确保指令以\r\n结尾
            const formattedCommand = command.endsWith('\r\n') ? command : command + '\r\n';
            
            // 发送AT指令
            connection.socket.write(formattedCommand);
            // logger.info(`AT指令已发送到 ${address}: ${formattedCommand.trim()}`);
            // logger.info(`待处理指令记录: ${commandKey}`);
            return true;
        } catch (error) {
            logger.error(`发送AT指令到 ${address} 失败:`, error);
            return false;
        }
    }

    /**
      * 设置AT指令响应回调函数
      */
     public setATResponseCallback(callback: (address: string, response: string) => void): void {
         if (!this.atResponseCallbacks.includes(callback)) {
             this.atResponseCallbacks.push(callback);
         }
     }

     /**
      * 移除AT指令响应回调函数
      */
     public removeATResponseCallback(callback: (address: string, response: string) => void): void {
         const index = this.atResponseCallbacks.indexOf(callback);
         if (index > -1) {
             this.atResponseCallbacks.splice(index, 1);
         }
     }

     /**
      * 清理超时的待处理指令
      */
     private cleanupPendingCommands(): void {
         const now = Date.now();
         const timeout = 20000; // 20秒超时，与websocket.io.ts保持一致
         
         this.pendingCommands.forEach((command, key) => {
             if (now - command.timestamp > timeout) {
                 logger.debug(`指令 ${command.commandType} 超时，已清理`);
                 this.pendingCommands.delete(key);
             }
         });
     }

}

export default TcpClient;